
package com.jf.cloud.supplier.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.jf.cloud.common.constant.Constant;
import com.jf.cloud.common.constant.IsPassShopEnum;
import com.jf.cloud.common.constant.StatusEnum;
import com.jf.cloud.common.exception.LuckException;
import com.jf.cloud.common.security.AuthUserContext;
import com.jf.cloud.supplier.constant.IsDefault;
import com.jf.cloud.supplier.constant.SupplierWithdrawCashStatus;
import com.jf.cloud.supplier.dto.SupplierBankCardDTO;
import com.jf.cloud.supplier.mapper.SupplierAuditingMapper;
import com.jf.cloud.supplier.mapper.SupplierBankCardMapper;
import com.jf.cloud.supplier.mapper.SupplierWithdrawCashMapper;
import com.jf.cloud.supplier.model.SupplierBankCard;
import com.jf.cloud.supplier.service.SupplierApplyService;
import com.jf.cloud.supplier.service.SupplierBankCardService;
import com.jf.cloud.supplier.vo.SupplierBankCardVO;
import ma.glasnost.orika.MapperFacade;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 银行卡信息
 *
 * @author zz
 * @date 2022-03-14 17:04:32
 */
@Service
public class SupplierBankCardServiceImpl implements SupplierBankCardService {

    @Autowired
    private SupplierBankCardMapper supplierBankCardMapper;

    @Autowired
    private SupplierWithdrawCashMapper supplierWithdrawCashMapper;

    @Autowired
    private SupplierAuditingMapper supplierAuditingMapper;

    @Autowired
    private SupplierApplyService supplierApplyService;

    @Autowired
    private MapperFacade mapperFacade;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertBatch(List<SupplierBankCardDTO> supplierBankCardDTOList, Long supplierId) {
        if (CollUtil.isEmpty(supplierBankCardDTOList)) {
            return;
        }
        List<SupplierBankCardVO> supplierBankCardVos = supplierBankCardMapper.listBySupplierId(supplierId);
        if (CollUtil.isEmpty(supplierBankCardVos)) {
            supplierBankCardVos = new ArrayList<>();
        }
        // 检查银行卡信息
        this.checkSaveBankCardList(supplierBankCardVos, supplierBankCardDTOList, supplierId);
        supplierBankCardMapper.insertBatch(supplierBankCardDTOList, supplierId);
    }

    @Override
    public List<SupplierBankCardVO> listBySupplierId(Long supplierId) {
        return supplierBankCardMapper.listBySupplierId(supplierId);
    }

    @Override
    public void deleteBySupplierBankCardId(Long supplierBankCardId, Long supplierId) {
        SupplierBankCardVO supplierBankCard = supplierBankCardMapper.getBySupplierBankCardId(supplierBankCardId);
        if (Objects.equals(supplierBankCard.getIsDefault(), 1)) {
            // 不能删除默认银行卡
            throw new LuckException("不能删除默认银行卡");
        }
        // 检查是否为最后一张银行卡
        if (supplierBankCardMapper.countBySupplierId(supplierId) == 1) {
            throw new LuckException("至少保留一张银行卡");
        }
        // 检查是否属于当前店铺
        this.checkIsCurrentSupplier(supplierId, supplierBankCardId);
        // 检查是否处于提现状态
        this.checkIsWithdraw(supplierBankCardId);
        // 进行删除
        supplierBankCardMapper.deleteById(supplierBankCardId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertBatchAndSubmitApply(List<SupplierBankCardDTO> supplierBankCardDTOList, Long supplierId) {
        if (Objects.equals(AuthUserContext.get().getIsPassShop(), IsPassShopEnum.YES.value())) {
            // 店铺已入驻不能调用该方法
            throw new LuckException("接口调用错误");
        }
        if (supplierBankCardDTOList == null || supplierBankCardDTOList.size() == 0) {
            throw new LuckException("至少要添加一个银行卡");
        }
        // 先删除已保存的银行卡信息
        supplierBankCardMapper.deleteBySupplierId(AuthUserContext.get().getTenantId());
        // 检查银行卡信息
        this.checkSaveBankCardList(new ArrayList<>(), supplierBankCardDTOList, supplierId);
        // 保存银行卡信息
        supplierBankCardMapper.insertBatch(supplierBankCardDTOList, supplierId);
        // 提交开店申请
        supplierApplyService.apply(supplierId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateBySupplierId(SupplierBankCardDTO supplierBankCardDTO, Long supplierId) {
        if (Objects.isNull(supplierBankCardDTO.getSupplierBankCardId())) {
            throw new LuckException("银行卡信息错误");
        }
        List<SupplierBankCardVO> supplierBankCardVOList = this.listBySupplierId(supplierId);
        // 检查银行卡是否属于当前店铺
        this.checkIsCurrentSupplier(supplierId, supplierBankCardDTO.getSupplierBankCardId());
        // 检查是否处于提现状态
        this.checkIsWithdraw(supplierBankCardDTO.getSupplierBankCardId());
        // 检查银行卡信息
        this.checkSaveBankCardList(supplierBankCardVOList, Collections.singletonList(supplierBankCardDTO), supplierId);
        supplierBankCardMapper.update(mapperFacade.map(supplierBankCardDTO, SupplierBankCard.class));
        if (Objects.equals(supplierBankCardDTO.getIsDefault(), IsDefault.YES.value())) {
            supplierBankCardMapper.setPrimary(supplierBankCardDTO.getSupplierBankCardId(), supplierId);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setPrimaryBySupplierId(Long supplierBankCardId, Long supplierId) {
        this.checkIsCurrentSupplier(supplierId, supplierBankCardId);
        supplierBankCardMapper.setPrimary(supplierBankCardId, supplierId);
    }

    @Override
    public void setNotPrimaryBySupplierId(Long supplierBankCardId, Long supplierId) {
        this.checkIsCurrentSupplier(supplierId, supplierBankCardId);
        supplierBankCardMapper.setNotPrimary(supplierBankCardId,supplierId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertBySupplierId(SupplierBankCardDTO supplierBankCardDTO, Long supplierId) {
        if (Objects.isNull(supplierBankCardDTO)) {
            return;
        }
        List<SupplierBankCardVO> supplierBankCardVOList = this.listBySupplierId(supplierId);
        if (CollUtil.isEmpty(supplierBankCardVOList)) {
            supplierBankCardVOList = new ArrayList<>();
        }
        // 检查银行卡信息
        this.checkSaveBankCardList(supplierBankCardVOList, Collections.singletonList(supplierBankCardDTO), supplierId);
        SupplierBankCard supplierBankCard = mapperFacade.map(supplierBankCardDTO, SupplierBankCard.class);
        supplierBankCard.setSupplierId(supplierId);
        supplierBankCard.setStatus(StatusEnum.ENABLE.value());
        supplierBankCardMapper.save(supplierBankCard);
        if (Objects.equals(supplierBankCardDTO.getIsDefault(), 1)) {
            supplierBankCardMapper.setPrimary(supplierBankCard.getSupplierBankCardId(), supplierId);
        }
    }

    @Override
    public SupplierBankCardVO getBySupplierBankCardId(Long supplierBankCardId) {
        return supplierBankCardMapper.getBySupplierBankCardId(supplierBankCardId);
    }

    @Override
    public SupplierBankCardVO getBySupplierBankCardIdAndSupplierId(Long supplierBankCardId, Long supplierId) {
        SupplierBankCardVO supplierBankCardVO = supplierBankCardMapper.getBySupplierBankCardId(supplierBankCardId);
        if (!Objects.equals(supplierBankCardVO.getSupplierId(), supplierId)) {
            throw new LuckException("当前银行卡不属于该店铺");
        }
        return supplierBankCardVO;
    }

    /**
     * 检查银行卡列表信息
     * @param savedBankCardList 已保存的银行卡列表
     * @param newBankCardList 新增的银行卡列表
     * @param supplierId 用于保存银行卡的店铺id
     */
    private void checkSaveBankCardList(List<SupplierBankCardVO> savedBankCardList, List<SupplierBankCardDTO> newBankCardList, Long supplierId) {
        if (savedBankCardList.size() + newBankCardList.size() > Constant.SHOP_BANK_CARD_LIMIT_NUM) {
            throw new LuckException("银行卡数量不能超过" + Constant.SHOP_BANK_CARD_LIMIT_NUM);
        }
        Map<String, Integer> bankCardMap = new HashMap<>(5);
        savedBankCardList.forEach(item -> {
            if (bankCardMap.containsKey(item.getCardNo())) {
                throw new LuckException("已添加的银行卡中存在重复账号" + item.getCardNo() + "，请先删除重复的银行卡账号");
            }
            bankCardMap.put(item.getCardNo(), 1);
        });
        newBankCardList.forEach(item -> {
            //新增的需要校验
            if (Objects.isNull(item.getSupplierBankCardId()) && bankCardMap.containsKey(item.getCardNo())) {
                throw new LuckException("银行卡账号" + item.getCardNo() + "重复");
            }
            bankCardMap.put(item.getCardNo(), 1);
        });
    }

    /**
     * 检查是否处于提现状态
     * @param supplierBankCardId 银行卡id
     */
    private void checkIsWithdraw(Long supplierBankCardId) {
        int count = supplierWithdrawCashMapper.countBySupplierBandCardIdAndStatus(supplierBankCardId, SupplierWithdrawCashStatus.WAITAUDIT.value());
        if (count > 0) {
            // 正在用于提现的银行卡不能删除
            throw new LuckException("正在用于提现的银行卡账号不能修改或删除");
        }
    }

    /**
     * 检查银行卡是否属于当前店铺
     * @param supplierId
     * @param supplierBankCardId
     */
    private void checkIsCurrentSupplier(Long supplierId, Long supplierBankCardId) {
        if (Objects.equals(supplierId, Constant.PLATFORM_SHOP_ID)) {
            // 平台端操作
            return;
        }
        SupplierBankCardVO supplierBankCard = this.supplierBankCardMapper.getBySupplierBankCardId(supplierBankCardId);
        if (!Objects.equals(supplierBankCard.getSupplierId(), supplierId)) {
            throw new LuckException("当前银行卡不属于你的店铺");
        }
    }
}
